package mini_app

import (
	"context"
	"fmt"
	"mini-app/config/mysql"
	"mini-app/internal/app/grpc/protoc/mini_app"
	"mini-app/internal/app/web/service"
	"mini-app/internal/dao"
	"mini-app/internal/define"
	"mini-app/internal/models"
	"time"

	"mini-app/internal/dal"
)

type MiniAppService struct {
	mini_app.UnimplementedMiniAppServiceServer
}

func (*MiniAppService) PickupNotify(ctx context.Context, req *mini_app.PickupNotifyReq) (*mini_app.PickupNotifyRsp, error) {
	res := &mini_app.PickupNotifyRsp{}
	if req.OutTradeNo == "" {
		res.Code = -1
		res.Msg = "订单号不能为空"
		return res, nil
	}
	if req.Status != 1 && req.Status != 2 {
		res.Code = -1
		res.Msg = "订单状态错误"
		return res, nil
	}
	orderInfo, _ := dao.Order{}.Detail(ctx, dal.Q, "", req.ChildOutTradeNo,
		req.OutTradeNo, "", "", define.OrderStatusToPickUp)
	if orderInfo == nil || orderInfo.ID == "" {
		res.Code = -1
		res.Msg = "订单不存在"
		return res, nil
	}

	// 修改订单信息
	tx := mysql.NewDB().Model(&models.Order{}).
		Where("batch_id = ?", req.OutTradeNo)
	if req.ChildOutTradeNo != "" {
		tx = tx.Where("id = ?", req.ChildOutTradeNo)
	}
	if req.Status == 1 { // 1 出货成功
		tx.Updates(map[string]interface{}{
			"pickup_status":   1,                               // 1 已出货
			"pickup_deadline": 0,                               // 取货截止时间置空
			"order_status":    define.OrderStatusPendingReview, // 订单状态 5已完成(待评价)
			"completed_at":    time.Now().Unix(),               // 订单完成时间
		})
	} else if req.Status == 2 { // 2 出货失败
		tx.Updates(map[string]interface{}{
			"pickup_code":     "", // 取货码置空
			"pickup_status":   0,  // 0 未取货
			"pickup_deadline": 0,  // 取货截止时间置空
		})
	}
	return res, nil
}

func (*MiniAppService) OrderStatusNotify(ctx context.Context, req *mini_app.OrderStatusNotifyReq) (*mini_app.OrderStatusNotifyRsp, error) {
	res := &mini_app.OrderStatusNotifyRsp{}
	orderInfo, _ := dao.Order{}.Detail(ctx, dal.Q, "", "", req.OutTradeNo, "", "", 0)
	if orderInfo == nil || orderInfo.ID == "" {
		return res, nil
	}
	var orderStatus int = 0
	if req.OrderStatus == 1 { // 创单
		orderStatus = define.OrderStatusUnpaid
	} else if req.OrderStatus == 2 { // 已支付
		// 2025-10-15 start guide_goods_price 导流商品支持价格（原导流商品为免费），这里增加支付和兑换码环节，支付后，需要输入兑换码才能出货
		if orderInfo.GoodsType == 2 && orderInfo.Amount != 0 { // 2为导流商品
			orderStatus = define.OrderStatusToPickUp
			// 2025-10-15 end guide_goods_price
		} else {
			orderStatus = define.OrderStatusToPickUp
		}

		/*else if lo.Contains([]int32{4, 5, 7}, req.OrderStatus) { // 4出货成功 5出货失败 7错误
			orderStatus = define.OrderStatusDone
		}*/

	} else if req.OrderStatus == 4 {
		orderStatus = define.OrderStatusDone
	} else if req.OrderStatus == 6 { // 已退款
		orderStatus = define.OrderStatusRefund
	}
	dao.Order{}.OrderStatusChange(ctx, dal.Q, "", req.OutTradeNo, orderStatus)
	if orderStatus == define.OrderStatusDone { // 更新订单状态为待评测
		dao.Order{}.UpdateOrderStatus(ctx, mysql.NewDB(), req.OutTradeNo, define.OrderStatusPendingReview)
	}
	return res, nil
}

func (*MiniAppService) GetOnlineEvent(ctx context.Context, req *mini_app.GetOnlineEventReq) (*mini_app.GetOnlineEventRsp, error) {
	res := &mini_app.GetOnlineEventRsp{}

	// 参数验证
	if req.Id == "" {
		res.Code = -1
		res.Msg = "活动ID不能为空"
		return res, nil
	}

	// 查询线上活动
	onlineEvent, err := dal.Q.OnlineEvent.WithContext(ctx).Where(dal.Q.OnlineEvent.ID.Eq(req.Id)).First()
	if err != nil {
		res.Code = -1
		res.Msg = "活动不存在"
		return res, nil
	}

	// 构建响应数据
	res.Code = 0
	res.Msg = "success"
	res.Data = &mini_app.OnlineEventInfo{
		Id:                 onlineEvent.ID,
		Name:               onlineEvent.Name,
		StartTime:          onlineEvent.StartTime,
		EndTime:            onlineEvent.EndTime,
		Status:             int32(onlineEvent.Status),
		RequirePoints:      onlineEvent.RequirePoints,
		RequireSupporters:  onlineEvent.RequireSupporters,
		ExpressFee:         onlineEvent.ExpressFee,
		Image:              onlineEvent.Image,
		GoodsId:            onlineEvent.GoodsID,
		LimitedFree:        onlineEvent.LimitedFree,
		PurchaseMethod:     int32(onlineEvent.PurchaseMethod),
		GoodsLink:          onlineEvent.GoodsLink,
		SelectedUser:       onlineEvent.SelectedUser,
		SelectedPuppetUser: onlineEvent.SelectedPuppetUser,
		JoinedUser:         onlineEvent.JoinedUser,
		BaseJoinedUser:     onlineEvent.BaseJoinedUser,
		Description:        onlineEvent.Description,
		CreatedAt:          onlineEvent.CreatedAt,
		UpdatedAt:          onlineEvent.UpdatedAt,
	}

	return res, nil
}

func (*MiniAppService) CreateOrder(ctx context.Context, req *mini_app.CreateOrderReq) (*mini_app.CreateOrderRsp, error) {
	res := &mini_app.CreateOrderRsp{}

	// 参数校验
	if len(req.List) == 0 {
		res.Code = -1
		res.Msg = "商品列表不能为空"
		return res, nil
	}

	userInfo, err := service.User{}.ProfileBy(ctx, "", req.Uid, "")
	if err != nil {
		res.Code = -1
		res.Msg = fmt.Sprintf("获取用户信息失败: %v", err)
		return res, nil
	}

	if userInfo == nil {
		res.Code = -1
		res.Msg = "用户不存在"
		return res, nil
	}

	if userInfo.ID == "" {
		res.Code = -1
		res.Msg = "用户不存在"
		return res, nil
	}

	if userInfo.OpenID == "" {
		res.Code = -1
		res.Msg = "用户未在小程序注册，请先注册"
		return res, nil
	}

	// 将 protobuf 的 CartRobotGoods 转换为 service 层的类型
	cartList := make([]service.CartRobotGoods, 0, len(req.List))
	for _, item := range req.List {
		cartList = append(cartList, service.CartRobotGoods{
			RobotID: item.RobotId,
			GoodsID: item.GoodsId,
			Count:   int(item.Count),
		})
	}

	var userAddress models.UserAddress
	if req.UserAddress != nil {
		// 将 protobuf 的 UserAddress 转换为 models.UserAddress
		userAddress = models.UserAddress{
			ID:            req.UserAddress.Id,
			OpenID:        req.UserAddress.Openid,
			Default:       req.UserAddress.Default,
			UserName:      req.UserAddress.UserName,
			TelNumber:     req.UserAddress.TelNumber,
			PostalCode:    req.UserAddress.PostalCode,
			ProvinceName:  req.UserAddress.ProvinceName,
			CityName:      req.UserAddress.CityName,
			CountyName:    req.UserAddress.CountyName,
			StreetName:    req.UserAddress.StreetName,
			DetailAddress: req.UserAddress.DetailAddress,
		}
	}

	// 调用 service 层创建订单
	orderResults, err := service.Order{}.CreateOrder(
		ctx,
		userInfo.OpenID,
		cartList,
		int(req.Cart),
		int(req.PurchaseMethod),
		userAddress,
		define.ConsumeMethodDef(req.ConsumeMethod),
		req.Code,
		int(req.UpdateOrderStatus),
	)

	if err != nil {
		res.Code = -1
		res.Msg = err.Error()
		return res, nil
	}

	// 转换结果为 protobuf 格式
	res.Code = 0
	res.Msg = "success"

	// 将所有订单结果转换为 protobuf 格式
	orderResList := make([]*mini_app.CreateOrderRes, 0, len(orderResults))
	for _, orderResult := range orderResults {
		orderResList = append(orderResList, &mini_app.CreateOrderRes{
			BatchId: orderResult.BatchID,
			Id:      orderResult.ID,
		})
	}

	res.Data = &mini_app.CreateOrderData{
		List: orderResList,
	}

	return res, nil
}

func (*MiniAppService) Pickup(ctx context.Context, req *mini_app.PickupReq) (*mini_app.PickupRsp, error) {
	res := &mini_app.PickupRsp{}

	// 参数校验
	if req.Openid == "" {
		res.Code = -1
		res.Msg = "用户openid不能为空"
		return res, nil
	}

	if req.BatchId == "" {
		res.Code = -1
		res.Msg = "订单批次号不能为空"
		return res, nil
	}

	// 调用 service 层的 Pickup 方法
	pickupInfo, err := service.Order{}.Pickup(
		ctx,
		req.RemoteIp,
		req.Openid,
		req.BatchId,
		req.RobotId,
		req.GoodsId,
	)

	if err != nil {
		res.Code = -1
		res.Msg = err.Error()
		return res, nil
	}

	// 转换结果为 protobuf 格式
	res.Code = 0
	res.Msg = "success"
	res.Data = &mini_app.PickupInfo{
		PickupDeadline: pickupInfo.PickupDeadline,
		PickupCode:     pickupInfo.PickupCode,
	}

	return res, nil
}

func (*MiniAppService) GetUserProfile(ctx context.Context, req *mini_app.GetUserProfileReq) (*mini_app.GetUserProfileRsp, error) {
	res := &mini_app.GetUserProfileRsp{}

	// 参数校验
	if req.Phone == "" && req.Openid == "" {
		return nil, fmt.Errorf("参数错误")
	}

	// 调用 service 层的 ProfileBy 方法
	// req.Openid为非nil，就以req.Openid为搜索条件；而req.Phone为非nil，就以req.Phone为搜索条件
	userInfo, err := service.User{}.ProfileBy(ctx, req.Openid, "", req.Phone)
	if err != nil {
		res.Code = -1
		res.Msg = fmt.Sprintf("查询用户错误：%s", err.Error())
		return res, nil
	}

	if userInfo == nil {
		res.Code = -1
		res.Msg = fmt.Sprintf("用户不存在")
		return res, nil
	}
	if userInfo.OpenID == "" {
		res.Code = -1
		res.Msg = fmt.Sprintf("用户不存在")
		return res, nil
	}

	// 转换结果为 protobuf 格式
	res.Data = &mini_app.UserProfile{
		Id:            userInfo.ID,
		NickName:      userInfo.NickName,
		Phone:         userInfo.Phone,
		Openid:        userInfo.OpenID,
		UserName:      userInfo.UserName,
		TelNumber:     userInfo.TelNumber,
		PostalCode:    userInfo.PostalCode,
		ProvinceName:  userInfo.ProvinceName,
		CityName:      userInfo.CityName,
		CountyName:    userInfo.CountyName,
		StreetName:    userInfo.StreetName,
		DetailAddress: userInfo.DetailAddress,
		Address:       userInfo.Address,
		Longitude:     userInfo.Longitude,
		Latitude:      userInfo.Latitude,
		Gender:        int32(userInfo.Gender),
		Birth:         userInfo.Birth,
		Email:         userInfo.Email,
		Hobby:         userInfo.Hobby,
		Image:         userInfo.Image,
		Points:        userInfo.Points,
		CreatedAt:     userInfo.CreatedAt,
		ChannelId:     userInfo.ChannelID,
	}

	return res, nil
}
